home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
355_01
/
slk1.exe
/
READ.ME
next >
Wrap
Text File
|
1991-06-11
|
24KB
|
627 lines
Sherlock Version 1.7. READ.ME file
Use 8 character tabs for best appearance of this file.
June 15, 1991
This is the first public domain version of Sherlock. Versions 1.5, 1.6 and 1.7
are identical except for bug fixes.
The file sherlock.doc contains the User's Manual for Sherlock. For a typeset
version of the manual, including an index, please send $15 to Edward K. Ream.
For the first time, version 1.7 contains the complete source code for the SPP
tool. Enjoy.
Although much of the code in this release is old and stable, this particular
release is relatively new. Please call if you have any problems with it.
REWARD
Although this is public domain software, a reward of $5.12 will be cheerfully
paid to the first person who reports any bug in any part of Sherlock.
I have no other plans to develop Sherlock further, though I am willing to
modify and improve Sherlock on a contract programming basis.
A preliminary version of Sherlock for the Macintosh is also available from:
The C Users' Group
2601 Iowa Street
Lawrence, KS 66046
PUBLIC DOMAIN SOFTWARE
Sherlock, including all files on this disk, is hereby placed into the public
domain by its sole author and owner,
Edward K. Ream
1617 Monroe Street
Madison, WI 53711
(608) 257-0802
Permission is hereby granted by Edward K. Ream to use and distribute any file
on this disk for any purpose whatever.
I welcome any questions or comments you may have about Sherlock. I am
available for commercial consulting on Sherlock at reasonable rates.
SYSTEM REQUIREMENTS
o An IBM PC/XT/AT computer or compatible with two floppy disks or a hard
disk and the MS-DOS operating system.
o Either the Microsoft C compiler or the Turbo C compiler. Minor
modifications in Sherlock's source code will allow Sherlock to compile using
other C compilers.
The code and make files on this disk were developed and tested using version
5.0 of the Microsoft compiler and version 2.0 of the Turbo C compiler.
FILES ON YOUR DISK
File Description
read.me This file.
*.mak Make files for the Turbo C compiler version 1.5.
*.mmk Make files for the Microsoft C compiler version
5.00 or later.
*.lnk Link files for the Turbo C linker.
*.ml Link files for the Microsoft linker.
dumpregs.c C Language source code for a program illustrating
the use of regs.asm.
prf.asm Assembly language source code for the interrupt
handler.
prfnear.obj Object code for interrupt handler for memory
models with small code spaces.
prffar.obj Object code for interrupt handler for memory
models with large code spaces.
measure.c Program to compute timing adjustments. (see below)
regs.asm Assembly language source code for the register
dumper.
regsnear.obj Object code for the register dumper for memory
models with small code spaces. (see below)
regsfar.obj Object code for the register dumper for memory
models with large code spaces. (see below)
sdel.exe Utility program which deletes all Sherlock macros
from a single source file.
sdel.c C language source code for SDEL illustrating the
use of Sherlock's macros.
sdif.exe Special purpose file comparison program.
sdif.c The C language source code for SDIF.
sherlock.c C language source code for Sherlock support routines.
sherlock.doc Complete Sherlock Users Manual.
sl.h Preferred definitions of macros.
sl1.h Alternate definitions of macros.
spp*.h Header files for the SPP tool.
spp*.c Source code for the SPP tool.
spp.exe Utility program which inserts Sherlock macros
into a single source file.
spp.doc The theory of operation of SPP.
sppnotes.doc Possible improvements to SPP.
QUICK START
This is the super-condensed version of the installation procedure. For more
detailed explanation of how to use sherlock, see the file sherlock.doc.
1. Insert Sherlock macros into all your sources files using the SPP tool. For
each file, use the -i option of SPP to insert the line #include "sl.h" at the
beginning of the file. Alternatively, if you have a single header file which is
inserted in all your source files, insert the line #include "sl.h" in the header file
and do *not* use the -i option. See the SPP section of sherlock.doc for more
details.
2. Recompile all your source files. Make sure to #define the compile time
symbol called SHERLOCK. The easiest and best way to do this is with a
command line option to the compiler.
3. Compile the source code for the Sherlock support routines, located in
sherlock.c. Make sure the memory model used when compiling the support
routines is the same as the memory model used when compiling the rest of the
files of your program. Sample make and link files to accomplish this step are
included in the directory called sherlock.
4. Link the following files together to produce an executable version of your
program:
o All the .obj files produced by compiling the files of your program.
o The .obj file produced by compiling sherlock.c.
o One (and only one) of the following two files: prffar.obj or prfnear.obj.
Note: Use prffar.obj when using memory models that have a code space larger
than 64K. Use prfnear when using memory models that have a code space
limited to 64K or less.
5. Run your program with ++* added to the command line to enable all
Sherlock traces. You will get lots of output. Eliminate unwanted traces by
rerunning your program with --xxx (in addition to ++*) to disable the tracing
for function xxx. Use --yyy* to disable tracing for all functions whose names
start with yyy. Alternatively, do not use ++* and instead enable tracing for
selected functions using ++xxx or ++yyy*. See sherlock.doc for a full
explanation of enabling and disabling tracing.
6. After debugging, it is easy to eliminate *all* the code produced by the
Sherlock macros *without* removing the macros from your source code. Just
#undef SHERLOCK and recompile all your source files and relink without
prfnear.obj, prffar.obj, or the object file produced from sherlock.c.
DISABLING UNNEEDED ROUTINES IN SHERLOCK.C
The following two #define statements appear near the beginning of sherlock.c:
#define MARKI 1
#define MARKII 1
You will be able to save quite a bit code space in your programs by commenting
out the statement which enables the version of the support routines which you
are NOT using.
In particular, comment out the MARKI constant when using either the Turbo C
or Microsoft C compiler.
KEEPING TRACK OF MEMORY MODELS
Please must make *sure* that the same memory model is used to compile *all*
the files that are linked together to form a single program. It is a good idea to
have the name of .obj files and .lib files reflect the memory model used to create
those files.
For example, all the .mak, .lnk, .mmk and .ml files supplied on this disk
assume that the following naming convention is used to name the .obj file
produced when sherlock.c is compiled:
slt.obj tiny memory model for Turbo C
sls.obj small memory model for Turbo C
slm.obj medium memory model for Turbo C
slc.obj compact memory model for Turbo C
sll.obj large memory model for Turbo C
slh.obj huge memory model for Turbo C
mslt.obj tiny memory model for Microsoft C
msls.obj small memory model for Microsoft C
mslm.obj medium memory model for Microsoft C
mslc.obj compact memory model for Microsoft C
msll.obj large memory model for Microsoft C
mslh.obj huge memory model for Microsoft C
When you change memory models, be sure to change *all* the references to
.obj and .lib files in your .mak, .lnk, .mmk or .ml files to correspond to the
new memory model.
.OBJ FILES
The Microsoft MASM assembler was used to produce the files prfnear.obj and
prffar.obj from the file prf.asm. These .obj files may be used with both the
Microsoft and the Turbo C linkers. You will not need MASM unless you want
to change the interrupt handler.
Important: Use prfnear.obj when using memory models that use only a single
code segment, i.e., the Microsoft tiny, small and compact models. Use
prffar.obj when using memory models that use multiple code segments, i.e., the
Microsoft medium, large and huge memory models.
MAKE AND LINK FILES
Make and link files are provided for the SDIF, SDEL and CPP tools. Each
make file refers to a corresponding link file. The following naming conventions
are used:
FILE EXTENSION CORRESPONDING PROGRAM
.mak Turbo C MAKE
.mmk Microsoft C MAKE
.lnk Turbo C TLINK
.ml Microsoft LINK
For each tool, the make and link files assume that directories are arranged as
follows:
TYPE OF FILE LOCATION
Source code root directory, e.g.,\sherlock
\sdel or \sdif
Microsoft .obj msc subdirectory
Turbo C .obj turboc subdirectory
Microsoft libraries c:\lib\msc
Turbo C libraries c:\lib\turboc
Microsoft include files c:\include\msc
Turbo C include files c:\include\turboc
Change the make and link files as appropriate to reflect how you have arranged
your directories. Also, be sure to change the make and link files to reflect
which memory model you are using.
USING OTHER DEBUGGERS WITH SHERLOCK
A program using Sherlock macros remains an ordinary C program. In
particular, you may use other debuggers such as debug or CodeView to debug
programs containing Sherlock macros.
USING SHERLOCK IN WINDOWING ENVIRONMENTS
Sherlock can be used in some windowing environments. First, use the -o
option SPP to write all tracing messages using the sl_cout() and related
routines.
Next, modify sl_cout(), defined in sherlock.c, to write a character to the
desired window. The sl_cout() routine consists solely of a single call to
putchar(), so modifying it should be easy.
KNOWN PROBLEMS
o The following code will generate a syntax error after being processed by SPP:
if (a) return; else ...
SPP will generate:
if (a) RETURN_VOID("function_name"); else ...
Alas, the RETURN_VOID macro expands to:
if (a) {sl_xv("function_name"); return}; else ...
The problem is that the semicolon after the } terminates the if statement! The
compiler will thus complain that the "else" does not match any "if." A good
workaround is to write:
if (a) { RETURN_VOID("function_name");} else ...
o Similarly, in functions returning structs or unions, the following code will
generate a syntax error after being processed by SPP:
if (a) return val; else ...
SPP will generate:
if (a) TICKX("function_name"); return val; else ...
Again, the compiler will complain that the "else" is not associated with the "if."
As before, a good workaround is to enclose the if clause in brackets:
if (a) { TICKX("function_name"); return val;} else ...
Note that this problem does not affect functions returning POINTERS to structs
or unions.
o The SPP tool sometimes inserts TICKX macros at the end of functions where
control can never reach. The only effect of this problem is to increase the size
of your program slightly. The Turbo C compiler will warn of such unreachable
code.
o SPP issues a warning if a cast occurs in an #if preprocessor directive. The
ANSI standard explicitly prohibits such casts, but Turbo C uses them in the file
limits.h. Also, SPP issues a warning in the Turbo C file graphics.h. These
warnings may safely be ignored.
o Sherlock macros generate many strings. When using the Microsoft C
compiler, it is a good idea to compile all files with the /Gt0 command line option
(The last character is zero.) This will place all data in separate segments so that
the limit of 64K in the stack segment will not be exceeded.
o Do not pass the address of a buffer whose contents may change to the SL_ON
or the SL_PARSE macros. For example, the following code will not work as
expected.
char name[100];
for (;;) {
printf("\nEnter tracepoint to be enabled: ");
gets(name);
if (name[0] != '\0') break;
sl_on(name);
}
The problem is that the SL_ON macro expects that the contents of name[] will
not change. Do something this instead:
char *p, name[100];
for (;;) {
printf("\nEnter tracepoint to be enabled: ");
gets(name);
if (name[0] != '\0') break;
p = malloc(strlen(name) + 1);
strcpy(p, name);
sl_on(p);
}
POSSIBLE IMPROVEMENTS TO SHERLOCK
The following is a list of improvements that could be made to Sherlock. Note
that I have no plans for actually making these improvements.
o When dealing with large projects containing dozens or hundreds of source
files, SPP should allow the output file produced by SPP to have the same name
as the input file. For safety's sake, SPP should create a temporary output file
and should remove the input file only it has been successfully processed
without serious errors. One way to do this would be to allow global
parameters on the command line, e.g., SPP *.c
o Along the same lines, it would be helpful to have a "batch" option to SPP.
Instead of including all the options to SPP on the command line, the batch
option would direct SPP to get options from a disk file.
o For statistics gathering, It would be useful to have an SPP option that would
cause SPP to generate only STATB and STATX macros.
o SPP would generate better looking files if it inserted #include <sl.h> before
the first #if or #include in the file, rather than at the start of the file.
o See the file sppnotes.doc for a list of possible design changes to SPP.
NEW FEATURES IN VERSION 1.5
o SPP v1.5 recognizes single-line comments, which start with // and continue to
the end of the line. As you would expect, the // sequence is treated as ordinary
characters in comments and inside strings. Single-line comments are not part of
the Draft ANSI C standard, but are offered as language extensions by several C
compilers, including the Microsoft C compiler.
A fine point: each single-line comment is converted to a single blank in the
replacement text of a #define preprocessor directive the // characters and any
following characters do not become part of the replacement text of the macro
being defined. This is consistent with how ordinary C comments are handled in
the Draft ANSI C Standard, and is also consistent with how current C++
compilers work. However, old C++ translators handled // differently.
Warning: the description of single-line comments on page 130 of The C++
Programming Language, by Bjarne Stroustrup, describes the anachronistic
operation of the old C++ translators, not current C and C++ compilers.
o The -x SPP option causes SPP not to recognize single-line comments.
o SPP v1.5 recognizes control-c interrupts in a new way, allowing you to type
another DOS command while SPP is running. Thanks are due to Stefan
Decuypere of Autographix for suggesting this improvement.
o The following paragraphs will be of interest only to advanced users of
Sherlock who wish to gather the best timing statistics possible. Thanks go to
James E.G. Morris of Atari Games Corporation for suggesting improvements
in the way timing statistics are handled.
Version 1.5 of the support routines provides ways to adjust the timing statistics
gathered by Sherlock to factor out the overhead caused by calling and returning
from the Sherlock macros. The Sherlock support routine sl_dump() now
subtracts a "fudge factor," called TIME_ADJUST, from the timing statistics as
the report of the statistics is being generated. This fudge factor affects only the
output of the SL_DUMP macro--the actual gathering of timing statistics is not
affected in any way by TIME_ADJUST.
The units of TIME_ADJUST are ticks per 1000 calls to Sherlock macros, and
TIME_ADJUST is supplied as a compile-time constant on the command line
when compiling sherlock.c. If no value for TIME_ADJUST is supplied, it is
set to zero, which is what you get by default.
The proper value of TIME_ADJUST depends on several factors: the speed of
your machine, its "tick" rate, the "speed up rate," i.e., the value of sl_speed
used in sherlock.c, which version of Sherlock macros is used, preferred or
alternate, and which memory model is used to compile your program. A new
utility program, called measure.c, measures the time overhead involved in
calling Sherlock macros, and suggests appropriate values for TIME_ADJUST.
OTHER NEW FEATURES
o SPP generates macros for a function only if the first executable statement of
that function is not already a Sherlock macro. SPP will generate the warning,
"Sherlock macros generated for this function," if a Sherlock macro is
encountered while generating macros for a function. That is, the warning will
be generated if the function contains Sherlock macros but the first executable
statement is not a Sherlock macro. This new feature is very handy--you can
now run your source files through SPP any time you add any function and SPP
will leave the functions already containing Sherlock macros alone.
o SPP supports the INCLUDE environment variable, which is set with the DOS
set command. For example, the DOS command:
set INCLUDE=c:\include;d:\sherlock
will cause SPP to search the c:\include and d:\sherlock directories for #include
files. The directories specified by the INCLUDE environment variable are
searched after any directories specified by the -s SPP option.
o Two new macros, SL_ENABLE() and SL_DISABLE(), allow function-by-
function control over SPP. Both macros always expand to empty code. Insert
SL_DISABLE() as the first executable statement of a function in which you
want no more Sherlock macros to be inserted. For example:
int f(void)
{
declarations;
SL_DISABLE();
No Sherlock macros will be generated in this function.
}
The SL_ENABLE() macro forces SPP to insert macros into a function. Use
this macro when a function starts with a Sherlock macro that you inserted
yourself. For example:
int do_command_line(int argc, char **argv)
{
declarations;
SL_ENABLE();
TRACEP("do_command_line",
for (i = 1; i < argc; i++) {
printf("argv[%d]: %s\n", argc, argv);
}
);
Sherlock macros will be generated as usual.
}
Be sure to delete the SL_ENABLE() macro after SPP processes the function.
o The SDEL -d option causes SDEL not to delete SL_DISABLE() macros.
o The SDIF -b option causes SDIF to display inserted or deleted lines
consisting only on blanks or tabs. By default SDIF does not display such lines
unless the -v option is in effect.
o SPP generates more compact code when using the -o option by generating
calls to three support routines: sl_lpout(void), sl_rpout(void) and
sl_csout(void). These new routines are equivalent to sl_cout("("), sl_sout(")"),
and sl_sout(", ") respectively.
o SPP generates printf statements that print Boolean arguments as either
"TRUE" or "FALSE" instead of 1 or 0. This is done using calls to a support
routine called sl_sbout(). The RETURN_BOOL macro is not affected by this
feature. For example, SPP will insert the following macros:
bool f(bool b)
{
TRACEPB("f", printf("(%s)\n", sl_sbout(b)));
...
RETURN_BOOL("f", 1);
}
o Tracepoint names may now contain up to 31 characters. Limiting tracepoint
names to 25 characters meant that not all proper function names were valid
tracepoint names.
BUGS FIXED in VERSION 1.7
o SPP now handles multiple #elif statements properly. (I think). This is the
least tested part of SPP. Please call if there is a problem.
o Several bug fixes were made to sem.c to handle types properly. Special
thanks to Roberto Artigas, Jr. for his help in this area.
BUGS FIXED BY VERSION 1.6
o The sl_level variable was made a global variable, as described in the manual.
o A bug was fixed that caused SPP to crash on some non-DOS systems. See
the file called st.c.
BUGS FIXED BY VERSION 1.5
o SPP generated a spurious error message if a function prototype contained the
[ ] operator. For example, the correct function prototype
void f(int[]);
generated the error message,
"unexpected '[' seen in a formal parameter list."
o SPP generated a spurious error message if the initializer of a structure
contained more than one open curly brace. For example, the following correct
code,
struct s {int i; int v[3];};
struct s s1 = {1,{0, 0, 0}};
generated the error message, "unexpected '{' in expression."
o SPP would incorrectly state that the file ended in a comment if the following
conditions held:
1. Nesting of comments was not allowed (the default condition).
2. A single comment contained /* within it.
3. The opening /* of the comment and the interior /* were on different lines.
For example:
/* ---------------
/* This is a comment */
o Macros which expanded into more than 600 characters caused SPP to crash.
SPP now issues a warning if a macro expands into more than 1000 characters
and truncates the expansion. SPP will still generate correct Sherlock macros
except in the unlikely event that truncating the macro expansion affects the type
of an object being traced.
o SPP used to generate a RETURN_PTR() macros for functions returning
structs or unions, as opposed to pointers to structs or unions. Such code
would not even compile correctly. SPP now generates a TICKX macro. For
example, given the following function:
struct s {a; int b};
struct s t;
struct s get_t()
{
...executable code...
return t;
}
SPP will generate the following macros:
struct s get_t()
{
TICKB("get_t");
.executable code.
TICKX("get_t");
return t;
}
There is no direct way for SPP to trace the valued returned from such functions.
The TICKX macro may be modified by hand to provide a more detailed trace.
BUGS FIXED BY VERSION 1.4
o SDIF improperly resynchronized in some cases, causing it to report changed
lines when in fact a back insertion had taken place.
BUGS FIXED BY VERSION 1.3
o SPP handled the SL_DISABLE() macro improperly: macro generation was
enabled if a Sherlock macro was encountered inside the function containing the
SL_DISABLE() macro.
BUGS FIXED BY VERSION 1.2
o Both SPP and SDEL inserted extra carriage returns before newlines. For
some compilers, debuggers and editors this was a really nasty bug--symptoms
included aborted compiles and meaningless line numbers in error messages.
o SPP did not allow constructions such as #if 0.
o SPP did not allow white space in the formal parameter list of a macro. For
instance,
#define max( a , b ) replacement text
caused the erroneous error message,
"#define ignored--formal arg must be an identifier."
o Preprocessor directives were not recognized in either of two circumstances,
1) The directive occurred in the very first line of an included file or,
2) The directive followed an #include directive in which the file was not found.
In either case, SPP gave an erroneous "unexpected # ignored" error message.
o SPP ignored the unsigned modifier, generating %d or %ld printf
specifications instead of %u or %lu specifications. Also, SPP generated calls to
a nonexistent routine named sl_uiout() for unsigned ints when the -o SPP
command line option was used.
o SPP only handled the special case of a pointer to char properly in a few
limited instances, i.e., only for formal parameters of a function where a typedef
was not used.